package cn.iocoder.yudao.module.train.controller.wechat.login.jwt.filter;

import cn.iocoder.yudao.module.train.controller.wechat.util.WxMiniUserContext;
import cn.iocoder.yudao.module.train.controller.wechat.login.jwt.service.IWxMiniJwtService;
import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;

/**
 * 微信小程序后台api接口校验过滤器
 *
 * @author weijiayu
 * @date 2025/4/22 23:48
 */
@Component
public class WxMiniJwtFilter extends OncePerRequestFilter {

    @Resource
    private IWxMiniJwtService jwtService;

    // 注入JWT启用状态配置（关键新增）
    @Value("${wechat.jwt.enabled:true}")  // 默认true，避免配置缺失导致问题
    private boolean jwtEnabled;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        if (!jwtEnabled) {
            filterChain.doFilter(request, response);
            return;
        }
        try {
            String path = request.getRequestURI();
            String error = JSON.toJSONString(error(401, "认证失败，无法访问系统资源"));
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            if (!this.checkIsExcludeUri(path) && path.startsWith("/wechat-api")) {
                /**
                 * 避免和若依框架默认的认证请求头key名Authorization冲突
                 * @see com.ruoyi.framework.config.SecurityConfig#filterChain
                 * @see com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter#doFilterInternal
                 */
                String token = request.getHeader("Wx-Authorization");
                if (token == null || !token.startsWith("Bearer ")) {
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    response.getWriter().write(error);
                    return;
                }

                // 提取JWT Token，去掉 "Bearer "前缀
                token = token.substring(7);
                try {
                    if (!jwtService.verifyToken(token)) {
                        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        response.getWriter().write(JSON.toJSONString(error));
                        return;
                    }
                    String userId = jwtService.parseUserId(token);
                    if (StringUtils.isEmpty(userId)) {
                        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        response.getWriter().write(JSON.toJSONString(error));
                        return;
                    }
                    WxMiniUserContext.setCurrentUserId(userId);
                } catch (Exception e) {
                    String message = e.getMessage();
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    error = JSON.toJSONString(error(401, "JWT validation failed: " + message));
                    response.getWriter().write(error);
                    return;
                }
            }
            filterChain.doFilter(request, response);
        } finally {
            WxMiniUserContext.clear();
        }
    }

    // 跳过无需鉴权的
    private boolean checkIsExcludeUri(String path) {
        return path.startsWith("/wechat-api/login");
    }
}
